package com.astrob.naviframe;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Point;
import android.net.Uri;

import android.os.Environment;
import android.util.FloatMath;
import android.view.MotionEvent;

import com.astrob.NavFrameSDK;
import com.astrob.model.FavoriteData;
import com.astrob.model.LonLat;
import com.astrob.model.SystemSetFileHandle;
import com.astrob.util.Utils;
import com.iflytek.tts.TtsService.TtsSpeaker;

@SuppressLint({ "SimpleDateFormat", "DefaultLocale" })
public class Start {

	private static Start instance = new Start();

	public static Start getInstance() {
		return instance;
	}

	public static String RUNDIR = Environment.getExternalStorageDirectory() + "/BHCMapper/";
	private String RUNDIR0 = Environment.getExternalStorageDirectory() + "/";

	private MapKit _mapkit;

	public MapKit MapKit() {
		return _mapkit;
	}

	private boolean searchRunDir(String rundir) {
		String paths[] = { "/mnt/", "/storage/", "/" };
		for (String path : paths) {
			File fRoot = new File(path);
			File[] files = fRoot.listFiles();
			if (files == null)
				continue;
			for (int j = 0; j < files.length; j++) {
				String fName = files[j].getName();
				if (fName.contains("Sd") || fName.contains("sd")) {
					if (files[j].isDirectory()) {
						RUNDIR = files[j].getPath() + rundir;
						String t = RUNDIR + "/Roam_d.clr";
						if (new File(t).exists()) {
							return true;
						} else {
							RUNDIR = "";
						}
					}
				}
			}
		}

		return false;
	}

	@SuppressWarnings("unused")
	private boolean searchRunDir(File fileold, int needNext) {
		String key = "BHCMapper";
		try {
			File[] files = fileold.listFiles();
			if (files.length > 0) {
				for (int j = 0; j < files.length; j++) {
					if (files[j].isDirectory()) {
						if (files[j].getName().indexOf(key) > -1) {
							RUNDIR = files[j].getPath();
							String t = RUNDIR + "/SMF01_d.cfg";
							if (new File(t).exists()) {
								return true;
							} else {
								RUNDIR = "";
							}
						} else {
							if (needNext > 0) {
								if (this.searchRunDir(files[j], needNext - 1)) {
									return true;
								}
							}
						}
					}
				}
			}
		} catch (Exception e) {

		}
		return false;
	}

	public boolean checkRundir() {
		boolean ret = false;
		String t = RUNDIR + "/Roam_d.clr";
		if (new File(t).exists()) {
			return true;
		}
		RUNDIR = "";

		if (RUNDIR.length() < 1) {
			searchRunDir("/BHCMapper/");
		}
		if (RUNDIR.length() > 1) {
			ret = true;
		}

		return ret;
	}

	public void copyMapFont(String dir) {
		String fontEPath = dir + "/font.ttf";
		String fontS0Path = "/system/fonts/DroidSansFallback.ttf";
		String fontS1Path = "/system/fonts/DFHEIA5A.ttf";
		String fontS2Path = "/system/fonts/NotoSansSC-Regular.otf";
		try {
			File file = new File(fontEPath);
			if (file.exists()) {
				return;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			File file = new File(fontS0Path);
			if (file.exists()) {
				Utils.copyFile(fontS0Path, fontEPath);
				return;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			File file = new File(fontS1Path);
			if (file.exists()) {
				Utils.copyFile(fontS1Path, fontEPath);
				return;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			File file = new File(fontS2Path);
			if (file.exists()) {
				Utils.copyFile(fontS2Path, fontEPath);
				return;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	boolean isAmap = false;
//	/storage/emulated/0/amapsdk/offlineMap/

	public boolean initialize(Context context) {
//		if (!checkRundir())
//			return false;
		//如果外置SD卡有运行环境则使用外置卡；否则使用内置卡
		String RUNDIRSD = "/mnt/sdcard2/BHCMapper/BHCMap/";
		String t = RUNDIRSD + "/Roam_d.clr";
		if (!new File(t).exists()) {
			RUNDIRSD = RUNDIR + "BHCMap/";
		}
		//----------

		boolean needRecopy = true;
		File file = new File(RUNDIRSD + "rundirVersion_1.0.1");
		if (file.exists()) {
			needRecopy = false;
		} else {
//			Utils.deleteDir(Utils.getSDPath() + File.separator + "BHCMapper");//这会导致创建文件失败
			deepFile(context, "BHCMapper", needRecopy);
		}
		_mapkit = new MapKit();
		if (isAmap) {
		} else {
			copyMapFont(RUNDIRSD);
			if (!_mapkit.initialize(RUNDIRSD))
				return false;
			File fileM = new File(RUNDIRSD + "maps/SH.smf");
			if (fileM.exists()) {
				haveMaps = true;
			}
		}
		return true;
	};

	public boolean haveMaps = false;

	public void deepFile(Context ctxDealFile, String path, boolean needRecopy) {
		try {
			String str[] = ctxDealFile.getAssets().list(path);
			if (str.length > 0) {//如果是目录
				File file = new File(RUNDIR0 + path);
				file.mkdirs();
				for (String string : str) {
					path = path + "/" + string;
					deepFile(ctxDealFile, path, needRecopy);
					path = path.substring(0, path.lastIndexOf('/'));
				}
			} else {//如果是文件
				InputStream is = ctxDealFile.getAssets().open(path);
				File outFile = new File(RUNDIR0+ path);
				if (!needRecopy && outFile.exists()) {
					return;
				}
				FileOutputStream fos = new FileOutputStream(outFile);
				byte[] buffer = new byte[1024];
				int count = 0;
				while (true) {
					count++;
					int len = is.read(buffer);
					if (len == -1) {
						break;
					}
					fos.write(buffer, 0, len);
				}
				is.close();
				fos.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void finalize() {
		if (_mapkit != null) {
			_mapkit.finalize();
		}

		if (mFout != null) {
			try {
				mFout.close();
				mFout = null;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private FileOutputStream mFout = null;

	public void log(String message) {
		message += "\n";
		if (mFout == null) {
			try {
				File file = new File(RUNDIR + "/log.txt");
				if (file.exists())
					file.delete();
				file.createNewFile();
				mFout = new FileOutputStream(RUNDIR + "/log.txt");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		try {
			byte[] bytes = message.getBytes();
			mFout.write(bytes);
			mFout.flush();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	String mSunriseTime = "";
	String mSunsetTime = "";

	// return format must be HH:mm
	public String getSunriseTime() {
		double lon = SystemSetFileHandle.getInstance().getSystemSet().previewLon;
		double lat = SystemSetFileHandle.getInstance().getSystemSet().previewLat;
		Date date = new Date();
		SimpleDateFormat dateformat = new SimpleDateFormat("D");
		String d = dateformat.format(date);
		int day = Integer.parseInt(d);
		double t = getSunrise(lon, lat, day);
		int hour = (int) t;
		double dm = (t - hour) * 60;
		int min = (int) dm;
		String ret = String.format("%02d:%02d", hour, min);
		return ret;
	}

	// return format must be HH:mm
	public String getSunsetTime() {
		double lon = SystemSetFileHandle.getInstance().getSystemSet().previewLon;
		double lat = SystemSetFileHandle.getInstance().getSystemSet().previewLat;
		Date date = new Date();
		SimpleDateFormat dateformat = new SimpleDateFormat("D");
		String d = dateformat.format(date);
		int day = Integer.parseInt(d);
		double t = getSunset(lon, lat, day);
		int hour = (int) t;
		double dm = (t - hour) * 60;
		int min = (int) dm;
		String ret = String.format("%02d:%02d", hour, min);
		return ret;
	}

	private int TIMEZONE = 8; // china time zone

	private double getSunrise(double lon, double lat, int day) {
		double pi = Math.PI;
		double degday = Math.cos(2 * pi * (day + 9) / 365);
		double diff = Math.acos(-Math.tan(-23.4 * degday * pi / 180)
				* Math.tan(lat * pi / 180))
				* 180 / pi;
		double t = 24 * (180 + TIMEZONE * 15 - lon - diff) / 360;
		return t;
	}

	private double getSunset(double lon, double lat, int day) {
		double sunrise = getSunrise(lon, lat, day);
		double t = 24 * (1 + (TIMEZONE * 15 - lon) / 180) - sunrise;
		return t;
	}

	static public class CountryItem {
		public CountryItem() {
			isHavemap = false;
			version = "V0.1";
			lon = 0;
			lat = 0;
			nRange = 10000;
			strDefaultCity = "";
			dScale = 3000;
			zName = "";
		}

		public LonLat getCenterLL() {
			LonLat ret = new LonLat();
			ret.SetLonLat(lon, lat);
			return ret;
		}

		public String ID;
		public boolean isHavemap;
		public String version;
		public float lon;
		public float lat;
		public int nRange;
		public String zName;
		public String strDefaultCity;
		public double dScale;
		public String strSmf;
		public String strDB;
		public String strBmf;
		public String strCitycfg;
		public int cfgIndex;
	}

	public ArrayList<CountryItem> mCountrylist = new ArrayList<Start.CountryItem>();

	@SuppressWarnings("unused")
	private void setCountrylist() {
		mCountrylist.clear();
		File file = new File(Start.RUNDIR + "/Country.CFG");
		if (null == file || file.exists() == false)
			return;

		try {
			FileInputStream f = new FileInputStream(file);
			DataInputStream in = new DataInputStream(f);

			int totallen = in.available();
			byte[] buf = new byte[totallen];
			int len = 0;
			StringBuilder name = new StringBuilder();
			while ((len = in.read(buf)) != -1) {
				name.append(new String(buf, 0, len, "gbk"));
			}

			String aa = name.toString();
			String[] type = aa.split("\r\n");
			for (int i = 0; i < type.length; i++) {
				CountryItem m = new CountryItem();
				if (type[i].compareToIgnoreCase("[SGP]") == 0) {
					m.ID = "SGP";
					m.strDefaultCity = "新加坡\nSingapore";
				} else if (type[i].compareToIgnoreCase("[Tha]") == 0) {
					m.ID = "Tha";
					m.strDefaultCity = "曼谷\nBangkok";
				} else if (type[i].compareToIgnoreCase("[HKG]") == 0) {
					m.ID = "HKG";
					m.strDefaultCity = "香港";
				} else if (type[i].compareToIgnoreCase("[MAC]") == 0) {
					m.ID = "MAC";
					m.strDefaultCity = "澳门";
				} else if (type[i].compareToIgnoreCase("[TWN]") == 0) {
					m.ID = "TWN";
					m.strDefaultCity = "台北市";
				} else if (type[i].compareToIgnoreCase("[CHI]") == 0) {
					m.ID = "CHI";
					m.strDefaultCity = "上海";
					// mSelectedCountryID = m.ID;
				} else {
					m.ID = type[i].substring(1, type[i].length() - 1);
				}

				// Y,V0.1
				i++;
				String[] item1 = type[i].split(",");
				if (item1[0].compareToIgnoreCase("Y") == 0) {
					m.isHavemap = true;
				}
				m.version = item1[1];

				// 103.849777,1.290025
				i++;
				String[] item2 = type[i].split(",");
				m.lon = Float.valueOf(item2[0]);
				m.lat = Float.valueOf(item2[1]);
				// range
				i++;
				m.nRange = Integer.parseInt(type[i]);
				// 国家中文名
				i++;
				m.zName = type[i];
				// strDefaultCity
				i++;
				if (m.strDefaultCity == null || m.strDefaultCity.length() == 0) {
					m.strDefaultCity = type[i];
				}
				// m.strDefaultCity = type[i]; //program defined
				// 3000
				i++;
				m.dScale = Float.valueOf(type[i]);

				// .SMF
				i++;
				m.strSmf = type[i];

				// .DB
				i++;
				m.strDB = type[i];

				// .BMF
				i++;
				m.strBmf = type[i];

				// .cfg ---- 如果是NULL，则为单一城市
				i++;
				m.strCitycfg = type[i];

				// .cfg
				i++;
				m.cfgIndex = Integer.parseInt(type[i]);

				mCountrylist.add(m);
			}
			in.close();
		} catch (Exception e) {
			// System.err.println("File input error!");
		}

	}

	public static Bitmap rotateBitmap(Bitmap bitmap, int degree) {
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		Matrix matrix = new Matrix();
		matrix.setRotate(degree);
		Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height,
				matrix, true);
		return newbmp;
	}

	public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
		if (bitmap == null) {
			return null;
		}
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		Matrix matrix = new Matrix();
		float scaleWidht = ((float) w / width);
		float scaleHeight = ((float) h / height);
		matrix.postScale(scaleWidht, scaleHeight);
		Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height,
				matrix, true);
		return newbmp;
	}

	// 求两点间距离：
	public double spacing(MotionEvent event) {
		float x = event.getX(0) - event.getX(1);
		float y = event.getY(0) - event.getY(1);
		return Math.sqrt(x * x + y * y);
	}


	private boolean mHavePath;

	public void setHavePath(boolean havePath) {
		mHavePath = havePath;
	}

	public boolean isHavePath() {
		return mHavePath;
	}

	//同航点，长按添加
	public List<FavoriteData> mFavList = new ArrayList<FavoriteData>();

	public ArrayList<LonLat> mMeasurelist = new ArrayList<LonLat>();


}
